/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package gmovil_jpa.controladores;

import gmovil_jpa.controladores.exceptions.IllegalOrphanException;
import gmovil_jpa.controladores.exceptions.NonexistentEntityException;
import gmovil_jpa.entidades.Plan;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import gmovil_jpa.entidades.TipoPagoPlan;
import gmovil_jpa.entidades.TipoClientePlan;
import gmovil_jpa.entidades.ValorAtributoPlan;
import java.util.ArrayList;
import java.util.List;
import gmovil_jpa.entidades.ModeloPlan;
import gmovil_jpa.entidades.DetalleFacturaPlan;

/**
 *
 * @author castlerock
 */
public class PlanJpaController {

    public PlanJpaController() {
        emf = Persistence.createEntityManagerFactory("gmovil_jpaPU");
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Plan plan) {
        if (plan.getValorAtributoPlanList() == null) {
            plan.setValorAtributoPlanList(new ArrayList<ValorAtributoPlan>());
        }
        if (plan.getModeloPlanList() == null) {
            plan.setModeloPlanList(new ArrayList<ModeloPlan>());
        }
        if (plan.getDetalleFacturaPlanList() == null) {
            plan.setDetalleFacturaPlanList(new ArrayList<DetalleFacturaPlan>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            TipoPagoPlan tipoPagoPlan = plan.getTipoPagoPlan();
            if (tipoPagoPlan != null) {
                tipoPagoPlan = em.getReference(tipoPagoPlan.getClass(), tipoPagoPlan.getIdTipoPagoPlan());
                plan.setTipoPagoPlan(tipoPagoPlan);
            }
            TipoClientePlan tipoClientePlan = plan.getTipoClientePlan();
            if (tipoClientePlan != null) {
                tipoClientePlan = em.getReference(tipoClientePlan.getClass(), tipoClientePlan.getIdTipoClientePlan());
                plan.setTipoClientePlan(tipoClientePlan);
            }
            List<ValorAtributoPlan> attachedValorAtributoPlanList = new ArrayList<ValorAtributoPlan>();
            for (ValorAtributoPlan valorAtributoPlanListValorAtributoPlanToAttach : plan.getValorAtributoPlanList()) {
                valorAtributoPlanListValorAtributoPlanToAttach = em.getReference(valorAtributoPlanListValorAtributoPlanToAttach.getClass(), valorAtributoPlanListValorAtributoPlanToAttach.getIdValorAtributoPlan());
                attachedValorAtributoPlanList.add(valorAtributoPlanListValorAtributoPlanToAttach);
            }
            plan.setValorAtributoPlanList(attachedValorAtributoPlanList);
            List<ModeloPlan> attachedModeloPlanList = new ArrayList<ModeloPlan>();
            for (ModeloPlan modeloPlanListModeloPlanToAttach : plan.getModeloPlanList()) {
                modeloPlanListModeloPlanToAttach = em.getReference(modeloPlanListModeloPlanToAttach.getClass(), modeloPlanListModeloPlanToAttach.getIdModeloPlan());
                attachedModeloPlanList.add(modeloPlanListModeloPlanToAttach);
            }
            plan.setModeloPlanList(attachedModeloPlanList);
            List<DetalleFacturaPlan> attachedDetalleFacturaPlanList = new ArrayList<DetalleFacturaPlan>();
            for (DetalleFacturaPlan detalleFacturaPlanListDetalleFacturaPlanToAttach : plan.getDetalleFacturaPlanList()) {
                detalleFacturaPlanListDetalleFacturaPlanToAttach = em.getReference(detalleFacturaPlanListDetalleFacturaPlanToAttach.getClass(), detalleFacturaPlanListDetalleFacturaPlanToAttach.getIdDetalleFacturaPlan());
                attachedDetalleFacturaPlanList.add(detalleFacturaPlanListDetalleFacturaPlanToAttach);
            }
            plan.setDetalleFacturaPlanList(attachedDetalleFacturaPlanList);
            em.persist(plan);
            if (tipoPagoPlan != null) {
                tipoPagoPlan.getPlanList().add(plan);
                tipoPagoPlan = em.merge(tipoPagoPlan);
            }
            if (tipoClientePlan != null) {
                tipoClientePlan.getPlanList().add(plan);
                tipoClientePlan = em.merge(tipoClientePlan);
            }
            for (ValorAtributoPlan valorAtributoPlanListValorAtributoPlan : plan.getValorAtributoPlanList()) {
                Plan oldPlanOfValorAtributoPlanListValorAtributoPlan = valorAtributoPlanListValorAtributoPlan.getPlan();
                valorAtributoPlanListValorAtributoPlan.setPlan(plan);
                valorAtributoPlanListValorAtributoPlan = em.merge(valorAtributoPlanListValorAtributoPlan);
                if (oldPlanOfValorAtributoPlanListValorAtributoPlan != null) {
                    oldPlanOfValorAtributoPlanListValorAtributoPlan.getValorAtributoPlanList().remove(valorAtributoPlanListValorAtributoPlan);
                    oldPlanOfValorAtributoPlanListValorAtributoPlan = em.merge(oldPlanOfValorAtributoPlanListValorAtributoPlan);
                }
            }
            for (ModeloPlan modeloPlanListModeloPlan : plan.getModeloPlanList()) {
                Plan oldPlanOfModeloPlanListModeloPlan = modeloPlanListModeloPlan.getPlan();
                modeloPlanListModeloPlan.setPlan(plan);
                modeloPlanListModeloPlan = em.merge(modeloPlanListModeloPlan);
                if (oldPlanOfModeloPlanListModeloPlan != null) {
                    oldPlanOfModeloPlanListModeloPlan.getModeloPlanList().remove(modeloPlanListModeloPlan);
                    oldPlanOfModeloPlanListModeloPlan = em.merge(oldPlanOfModeloPlanListModeloPlan);
                }
            }
            for (DetalleFacturaPlan detalleFacturaPlanListDetalleFacturaPlan : plan.getDetalleFacturaPlanList()) {
                Plan oldPlanOfDetalleFacturaPlanListDetalleFacturaPlan = detalleFacturaPlanListDetalleFacturaPlan.getPlan();
                detalleFacturaPlanListDetalleFacturaPlan.setPlan(plan);
                detalleFacturaPlanListDetalleFacturaPlan = em.merge(detalleFacturaPlanListDetalleFacturaPlan);
                if (oldPlanOfDetalleFacturaPlanListDetalleFacturaPlan != null) {
                    oldPlanOfDetalleFacturaPlanListDetalleFacturaPlan.getDetalleFacturaPlanList().remove(detalleFacturaPlanListDetalleFacturaPlan);
                    oldPlanOfDetalleFacturaPlanListDetalleFacturaPlan = em.merge(oldPlanOfDetalleFacturaPlanListDetalleFacturaPlan);
                }
            }
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Plan plan) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Plan persistentPlan = em.find(Plan.class, plan.getIdPlan());
            TipoPagoPlan tipoPagoPlanOld = persistentPlan.getTipoPagoPlan();
            TipoPagoPlan tipoPagoPlanNew = plan.getTipoPagoPlan();
            TipoClientePlan tipoClientePlanOld = persistentPlan.getTipoClientePlan();
            TipoClientePlan tipoClientePlanNew = plan.getTipoClientePlan();
            List<ValorAtributoPlan> valorAtributoPlanListOld = persistentPlan.getValorAtributoPlanList();
            List<ValorAtributoPlan> valorAtributoPlanListNew = plan.getValorAtributoPlanList();
            List<ModeloPlan> modeloPlanListOld = persistentPlan.getModeloPlanList();
            List<ModeloPlan> modeloPlanListNew = plan.getModeloPlanList();
            List<DetalleFacturaPlan> detalleFacturaPlanListOld = persistentPlan.getDetalleFacturaPlanList();
            List<DetalleFacturaPlan> detalleFacturaPlanListNew = plan.getDetalleFacturaPlanList();
            List<String> illegalOrphanMessages = null;
            for (ValorAtributoPlan valorAtributoPlanListOldValorAtributoPlan : valorAtributoPlanListOld) {
                if (!valorAtributoPlanListNew.contains(valorAtributoPlanListOldValorAtributoPlan)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain ValorAtributoPlan " + valorAtributoPlanListOldValorAtributoPlan + " since its plan field is not nullable.");
                }
            }
            for (ModeloPlan modeloPlanListOldModeloPlan : modeloPlanListOld) {
                if (!modeloPlanListNew.contains(modeloPlanListOldModeloPlan)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain ModeloPlan " + modeloPlanListOldModeloPlan + " since its plan field is not nullable.");
                }
            }
            for (DetalleFacturaPlan detalleFacturaPlanListOldDetalleFacturaPlan : detalleFacturaPlanListOld) {
                if (!detalleFacturaPlanListNew.contains(detalleFacturaPlanListOldDetalleFacturaPlan)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain DetalleFacturaPlan " + detalleFacturaPlanListOldDetalleFacturaPlan + " since its plan field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (tipoPagoPlanNew != null) {
                tipoPagoPlanNew = em.getReference(tipoPagoPlanNew.getClass(), tipoPagoPlanNew.getIdTipoPagoPlan());
                plan.setTipoPagoPlan(tipoPagoPlanNew);
            }
            if (tipoClientePlanNew != null) {
                tipoClientePlanNew = em.getReference(tipoClientePlanNew.getClass(), tipoClientePlanNew.getIdTipoClientePlan());
                plan.setTipoClientePlan(tipoClientePlanNew);
            }
            List<ValorAtributoPlan> attachedValorAtributoPlanListNew = new ArrayList<ValorAtributoPlan>();
            for (ValorAtributoPlan valorAtributoPlanListNewValorAtributoPlanToAttach : valorAtributoPlanListNew) {
                valorAtributoPlanListNewValorAtributoPlanToAttach = em.getReference(valorAtributoPlanListNewValorAtributoPlanToAttach.getClass(), valorAtributoPlanListNewValorAtributoPlanToAttach.getIdValorAtributoPlan());
                attachedValorAtributoPlanListNew.add(valorAtributoPlanListNewValorAtributoPlanToAttach);
            }
            valorAtributoPlanListNew = attachedValorAtributoPlanListNew;
            plan.setValorAtributoPlanList(valorAtributoPlanListNew);
            List<ModeloPlan> attachedModeloPlanListNew = new ArrayList<ModeloPlan>();
            for (ModeloPlan modeloPlanListNewModeloPlanToAttach : modeloPlanListNew) {
                modeloPlanListNewModeloPlanToAttach = em.getReference(modeloPlanListNewModeloPlanToAttach.getClass(), modeloPlanListNewModeloPlanToAttach.getIdModeloPlan());
                attachedModeloPlanListNew.add(modeloPlanListNewModeloPlanToAttach);
            }
            modeloPlanListNew = attachedModeloPlanListNew;
            plan.setModeloPlanList(modeloPlanListNew);
            List<DetalleFacturaPlan> attachedDetalleFacturaPlanListNew = new ArrayList<DetalleFacturaPlan>();
            for (DetalleFacturaPlan detalleFacturaPlanListNewDetalleFacturaPlanToAttach : detalleFacturaPlanListNew) {
                detalleFacturaPlanListNewDetalleFacturaPlanToAttach = em.getReference(detalleFacturaPlanListNewDetalleFacturaPlanToAttach.getClass(), detalleFacturaPlanListNewDetalleFacturaPlanToAttach.getIdDetalleFacturaPlan());
                attachedDetalleFacturaPlanListNew.add(detalleFacturaPlanListNewDetalleFacturaPlanToAttach);
            }
            detalleFacturaPlanListNew = attachedDetalleFacturaPlanListNew;
            plan.setDetalleFacturaPlanList(detalleFacturaPlanListNew);
            plan = em.merge(plan);
            if (tipoPagoPlanOld != null && !tipoPagoPlanOld.equals(tipoPagoPlanNew)) {
                tipoPagoPlanOld.getPlanList().remove(plan);
                tipoPagoPlanOld = em.merge(tipoPagoPlanOld);
            }
            if (tipoPagoPlanNew != null && !tipoPagoPlanNew.equals(tipoPagoPlanOld)) {
                tipoPagoPlanNew.getPlanList().add(plan);
                tipoPagoPlanNew = em.merge(tipoPagoPlanNew);
            }
            if (tipoClientePlanOld != null && !tipoClientePlanOld.equals(tipoClientePlanNew)) {
                tipoClientePlanOld.getPlanList().remove(plan);
                tipoClientePlanOld = em.merge(tipoClientePlanOld);
            }
            if (tipoClientePlanNew != null && !tipoClientePlanNew.equals(tipoClientePlanOld)) {
                tipoClientePlanNew.getPlanList().add(plan);
                tipoClientePlanNew = em.merge(tipoClientePlanNew);
            }
            for (ValorAtributoPlan valorAtributoPlanListNewValorAtributoPlan : valorAtributoPlanListNew) {
                if (!valorAtributoPlanListOld.contains(valorAtributoPlanListNewValorAtributoPlan)) {
                    Plan oldPlanOfValorAtributoPlanListNewValorAtributoPlan = valorAtributoPlanListNewValorAtributoPlan.getPlan();
                    valorAtributoPlanListNewValorAtributoPlan.setPlan(plan);
                    valorAtributoPlanListNewValorAtributoPlan = em.merge(valorAtributoPlanListNewValorAtributoPlan);
                    if (oldPlanOfValorAtributoPlanListNewValorAtributoPlan != null && !oldPlanOfValorAtributoPlanListNewValorAtributoPlan.equals(plan)) {
                        oldPlanOfValorAtributoPlanListNewValorAtributoPlan.getValorAtributoPlanList().remove(valorAtributoPlanListNewValorAtributoPlan);
                        oldPlanOfValorAtributoPlanListNewValorAtributoPlan = em.merge(oldPlanOfValorAtributoPlanListNewValorAtributoPlan);
                    }
                }
            }
            for (ModeloPlan modeloPlanListNewModeloPlan : modeloPlanListNew) {
                if (!modeloPlanListOld.contains(modeloPlanListNewModeloPlan)) {
                    Plan oldPlanOfModeloPlanListNewModeloPlan = modeloPlanListNewModeloPlan.getPlan();
                    modeloPlanListNewModeloPlan.setPlan(plan);
                    modeloPlanListNewModeloPlan = em.merge(modeloPlanListNewModeloPlan);
                    if (oldPlanOfModeloPlanListNewModeloPlan != null && !oldPlanOfModeloPlanListNewModeloPlan.equals(plan)) {
                        oldPlanOfModeloPlanListNewModeloPlan.getModeloPlanList().remove(modeloPlanListNewModeloPlan);
                        oldPlanOfModeloPlanListNewModeloPlan = em.merge(oldPlanOfModeloPlanListNewModeloPlan);
                    }
                }
            }
            for (DetalleFacturaPlan detalleFacturaPlanListNewDetalleFacturaPlan : detalleFacturaPlanListNew) {
                if (!detalleFacturaPlanListOld.contains(detalleFacturaPlanListNewDetalleFacturaPlan)) {
                    Plan oldPlanOfDetalleFacturaPlanListNewDetalleFacturaPlan = detalleFacturaPlanListNewDetalleFacturaPlan.getPlan();
                    detalleFacturaPlanListNewDetalleFacturaPlan.setPlan(plan);
                    detalleFacturaPlanListNewDetalleFacturaPlan = em.merge(detalleFacturaPlanListNewDetalleFacturaPlan);
                    if (oldPlanOfDetalleFacturaPlanListNewDetalleFacturaPlan != null && !oldPlanOfDetalleFacturaPlanListNewDetalleFacturaPlan.equals(plan)) {
                        oldPlanOfDetalleFacturaPlanListNewDetalleFacturaPlan.getDetalleFacturaPlanList().remove(detalleFacturaPlanListNewDetalleFacturaPlan);
                        oldPlanOfDetalleFacturaPlanListNewDetalleFacturaPlan = em.merge(oldPlanOfDetalleFacturaPlanListNewDetalleFacturaPlan);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = plan.getIdPlan();
                if (findPlan(id) == null) {
                    throw new NonexistentEntityException("The plan with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Plan plan;
            try {
                plan = em.getReference(Plan.class, id);
                plan.getIdPlan();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The plan with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            List<ValorAtributoPlan> valorAtributoPlanListOrphanCheck = plan.getValorAtributoPlanList();
            for (ValorAtributoPlan valorAtributoPlanListOrphanCheckValorAtributoPlan : valorAtributoPlanListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Plan (" + plan + ") cannot be destroyed since the ValorAtributoPlan " + valorAtributoPlanListOrphanCheckValorAtributoPlan + " in its valorAtributoPlanList field has a non-nullable plan field.");
            }
            List<ModeloPlan> modeloPlanListOrphanCheck = plan.getModeloPlanList();
            for (ModeloPlan modeloPlanListOrphanCheckModeloPlan : modeloPlanListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Plan (" + plan + ") cannot be destroyed since the ModeloPlan " + modeloPlanListOrphanCheckModeloPlan + " in its modeloPlanList field has a non-nullable plan field.");
            }
            List<DetalleFacturaPlan> detalleFacturaPlanListOrphanCheck = plan.getDetalleFacturaPlanList();
            for (DetalleFacturaPlan detalleFacturaPlanListOrphanCheckDetalleFacturaPlan : detalleFacturaPlanListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Plan (" + plan + ") cannot be destroyed since the DetalleFacturaPlan " + detalleFacturaPlanListOrphanCheckDetalleFacturaPlan + " in its detalleFacturaPlanList field has a non-nullable plan field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            TipoPagoPlan tipoPagoPlan = plan.getTipoPagoPlan();
            if (tipoPagoPlan != null) {
                tipoPagoPlan.getPlanList().remove(plan);
                tipoPagoPlan = em.merge(tipoPagoPlan);
            }
            TipoClientePlan tipoClientePlan = plan.getTipoClientePlan();
            if (tipoClientePlan != null) {
                tipoClientePlan.getPlanList().remove(plan);
                tipoClientePlan = em.merge(tipoClientePlan);
            }
            em.remove(plan);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Plan> findPlanEntities() {
        return findPlanEntities(true, -1, -1);
    }

    public List<Plan> findPlanEntities(int maxResults, int firstResult) {
        return findPlanEntities(false, maxResults, firstResult);
    }

    private List<Plan> findPlanEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Plan.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Plan findPlan(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Plan.class, id);
        } finally {
            em.close();
        }
    }

    public int getPlanCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Plan> rt = cq.from(Plan.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

}
